import { Get, Post, Body, Put, Delete, Param, Query, Controller, UsePipes, HttpStatus } from '@nestjs/common';
import { UserService } from './user.service';
import { UserMessage } from './user.message';
import { CreateUserDto, UpdateUserDto, LoginUserDto } from './dto';
import { HttpException } from '@nestjs/common/exceptions/http.exception';
import { ValidationPipe } from '../shared/pipes/validation.pipe';
import { ApiUseTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { ResponseData } from '../shared/base.interface';
import { ResponseCode } from '../shared/base.responseCode';

const R = require('ramda');

@ApiBearerAuth()
@ApiUseTags('用户管理')
@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @ApiOperation({ title: '根据用户id获取用户信息' })
  @Get()
  async findMe(@Query('userId') userId: number): Promise<ResponseData> {
    return await this.userService.findById(userId);
  }

  @ApiOperation({ title: '根据用户id更新用户信息' })
  @UsePipes(new ValidationPipe())
  @Put()
  async update(
    @Body() userData: UpdateUserDto,
  ) {
    return await this.userService.update(userData);
  }

  @ApiOperation({ title: '根据用户id删除用户信息' })
  @Delete('/:userId')
  async delete(@Param('userId') userId: string) {
    return await this.userService.delete(userId);
  }

  @ApiOperation({ title: '用户注册' })
  @UsePipes(new ValidationPipe())
  @Post()
  async create(@Body() userData: CreateUserDto) {
    return this.userService.create(userData);
  }

  @ApiOperation({ title: '用户登录' })
  @UsePipes(new ValidationPipe())
  @Post('/login')
  async login(@Body() loginUserDto: LoginUserDto): Promise<ResponseData> {
    const userInfo = await this.userService.findOne(loginUserDto);

    const errorInfo: ResponseData = {
      code: ResponseCode.fail,
      message: UserMessage.loginInputFail,
    };
    if (!userInfo) {
      throw new HttpException(errorInfo, HttpStatus.UNAUTHORIZED);
    }

    const token = await this.userService.generateJWT(userInfo);
    const newUser = R.omit(['password'], userInfo);
    const user = { token, ...newUser };
    return {
      code: ResponseCode.ok,
      message: UserMessage.loginOk,
      data: user,
    };
  }
}
